home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / text / hyper / ManualBrows1_1.lha / main.c < prev    next >
C/C++ Source or Header  |  1994-11-12  |  15KB  |  612 lines

  1. /************************************************************************/
  2. /*                                    */
  3. /*  Copyright (C) 1994  Christian Stieber                */
  4. /*                                    */
  5. /* This program is free software; you can redistribute it and/or modify    */
  6. /* it under the terms of the GNU General Public License as published by    */
  7. /* the Free Software Foundation; either version 2 of the License, or    */
  8. /* (at your option) any later version.                    */
  9. /*                                    */
  10. /* This program is distributed in the hope that it will be useful,    */
  11. /* but WITHOUT ANY WARRANTY; without even the implied warranty of    */
  12. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    */
  13. /* GNU General Public License for more details.                */
  14. /*                                    */
  15. /* You should have received a copy of the GNU General Public License    */
  16. /* along with this program; if not, write to the Free Software        */
  17. /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.        */
  18. /*                                    */
  19. /************************************************************************/
  20. /*                                    */
  21. /* Author address:                            */
  22. /*   Christian Stieber                            */
  23. /*   Konradstraße 41                            */
  24. /*   D-85055 Ingolstadt                            */
  25. /*   (Germany)                                */
  26. /*   Phone: 0841-59896                            */
  27. /*                                    */
  28. /************************************************************************/
  29.  
  30. #ifndef V39
  31.    #define CreatePool LibCreatePool
  32.    #define DeletePool LibDeletePool
  33.    #define AllocPooled LibAllocPooled
  34.    #define FreePooled LibFreePooled
  35. #endif
  36.  
  37. #ifndef DOS_DOSEXTENS_H
  38. #include <dos/dosextens.h>
  39. #endif
  40.  
  41. #ifndef DOS_EXALL_H
  42. #include <dos/exall.h>
  43. #endif
  44.  
  45. #ifndef INTUITION_INTUITION_H
  46. #include <intuition/intuition.h>
  47. #endif
  48.  
  49. #ifndef LIBRARIES_AMIGAGUIDE_H
  50. #include <libraries/amigaguide.h>
  51. #endif
  52.  
  53. #ifndef WORKBENCH_STARTUP_H
  54. #include <workbench/startup.h>
  55. #endif
  56.  
  57. #ifndef WORKBENCH_WORKBENCH_H
  58. #include <workbench/workbench.h>
  59. #endif
  60.  
  61. #ifndef __GNUC__
  62.    #ifndef CLIB_EXEC_PROTOS_H
  63.    #include <clib/exec_protos.h>
  64.    #endif
  65.  
  66.    #ifndef CLIB_DOS_PROTOS_H
  67.    #include <clib/dos_protos.h>
  68.    #endif
  69.  
  70.    #ifndef CLIB_UTILITY_PROTOS_H
  71.    #include <clib/utility_protos.h>
  72.    #endif
  73.  
  74.    #ifndef CLIB_INTUITION_PROTOS_H
  75.    #include <clib/intuition_protos.h>
  76.    #endif
  77.  
  78.    #ifndef CLIB_ICON_PROTOS_H
  79.    #include <clib/icon_protos.h>
  80.    #endif
  81.  
  82.    #ifndef CLIB_AMIGAGUIDE_PROTOS_H
  83.    #include <clib/amigaguide_protos.h>
  84.    #endif
  85.  
  86.    #include <pragmas/exec_pragmas.h>
  87.    #include <pragmas/dos_pragmas.h>
  88.    #include <pragmas/intuition_pragmas.h>
  89.    #include <pragmas/utility_pragmas.h>
  90.    #include <pragmas/icon_pragmas.h>
  91.    #include <pragmas/amigaguide_pragmas.h>
  92. #endif
  93.  
  94. #include <string.h>
  95.  
  96. #include "Globals.h"
  97.  
  98. /***********************************************/
  99.  
  100. struct DosLibrary *DOSBase;
  101. struct IntuitionBase *IntuitionBase;
  102. struct Library *AmigaGuideBase;
  103. struct Library *UtilityBase;
  104.  
  105. /***********************************************/
  106.  
  107. #ifdef __GNUC__
  108.  
  109. #include "Inlines.h"
  110.  
  111. #ifndef V39
  112.    APTR AllocPooled(APTR, ULONG);
  113.    void FreePooled(APTR, APTR, ULONG);
  114.    APTR CreatePool(ULONG, ULONG, ULONG);
  115.    void DeletePool(APTR);
  116. #endif
  117.  
  118. #endif   /* __GNUC__ */
  119.  
  120. /***********************************************/
  121.  
  122. #define CONFIGFILE    "ManualBrowser.config"
  123.  
  124. /***********************************************/
  125.  
  126. char Version[]="$VER: ManualBrowser " PROGVERSION " (" PROGDATE ")"
  127. #ifdef V39
  128. "(V39) "
  129. #endif
  130. "(" CPU ") "
  131. "© 1994 Christian Stieber";
  132.  
  133. /***********************************************/
  134.  
  135. #define BASENAME   "ManBrowser"
  136. #define PUDDLESIZE (20*1024)
  137.  
  138. /***********************************************/
  139.  
  140. struct ActionNode *ActionList;
  141. BPTR ManDir;
  142. long LineLength=70;
  143. char DatabaseName[64];
  144.  
  145. /***********************************************/
  146.  
  147. static void *MemoryPool;
  148.  
  149. static AMIGAGUIDEHOST AmigaGuideHostHandle;
  150. static AMIGAGUIDECONTEXT AmigaGuideHandle;
  151.  
  152. static char Filename[64];
  153.  
  154. static BPTR FileHandle;
  155.  
  156. static struct WBStartup *WBStartupMessage;
  157.  
  158. static struct EasyStruct EasyStruct=
  159.    {
  160.       5*4,
  161.       0,
  162.       "Manual browser " PROGVERSION " error",
  163.       NULL,
  164.       NULL
  165.    };
  166.  
  167. /***********************************************/
  168.  
  169. #ifdef __GNUC__
  170. static void MyExit(int) __attribute__((noreturn));
  171. #endif
  172.  
  173. static void MyExit(int RC)
  174.  
  175. {
  176.    if (WBStartupMessage)
  177.       {
  178.          Forbid();
  179.          ReplyMsg((struct Message *)WBStartupMessage);
  180.       }
  181.    exit(RC);
  182. }
  183.  
  184. /************************************************************************/
  185. /*                                    */
  186. /* Malloc()                                */
  187. /*                                    */
  188. /************************************************************************/
  189.  
  190. void *Malloc(ULONG Size)
  191.  
  192. {
  193.    ULONG *Memory;
  194.  
  195.    Size+=4;
  196.    if (Memory=AllocPooled(MemoryPool,Size))
  197.       {
  198.          *Memory=Size;
  199.          Memory++;
  200.       }
  201.    return Memory;
  202. }
  203.  
  204. /************************************************************************/
  205. /*                                    */
  206. /* Free()                                */
  207. /*                                    */
  208. /************************************************************************/
  209.  
  210. void Free(void *Memory)
  211.  
  212. {
  213.    if (Memory)
  214.       {
  215.          FreePooled(MemoryPool,((ULONG *)Memory)-1,*(((ULONG *)Memory)-1));
  216.       }
  217. }
  218.  
  219. /***********************************************/
  220.  
  221. static void DisplayError(char *Format,...)
  222.  
  223. {
  224.    if (WBStartupMessage)
  225.       {
  226.          EasyStruct.es_TextFormat=Format;
  227.          EasyStruct.es_GadgetFormat="Quit";
  228.          EasyRequestArgs(NULL,&EasyStruct,NULL,(&Format)+1);
  229.       }
  230.    else
  231.       {
  232.          VPrintf(Format,(&Format)+1);
  233.          PutStr("\n");
  234.       }
  235. }
  236.  
  237. /***********************************************/
  238.  
  239. static void DisplayDosError(char *Filename)
  240.  
  241. {
  242.    if (WBStartupMessage)
  243.       {
  244.          char Buffer[256];
  245.          char *t;
  246.  
  247.          t=Buffer;
  248.          Fault(IoErr(),Filename,t,sizeof(Buffer));
  249.          EasyStruct.es_TextFormat="%s";
  250.          EasyStruct.es_GadgetFormat="Quit";
  251.          EasyRequestArgs(NULL,&EasyStruct,NULL,&t);
  252.       }
  253.    else
  254.       {
  255.          PrintFault(IoErr(),Filename);
  256.       }
  257. }
  258.  
  259. /***********************************************/
  260.  
  261. #ifdef __GNUC__
  262. static void CloseAll(int) __attribute__((noreturn));
  263. #endif
  264.  
  265. static void CloseAll(int RC)
  266.  
  267. {
  268.    if (AmigaGuideHandle) CloseAmigaGuide(AmigaGuideHandle);
  269.    if (AmigaGuideHostHandle)
  270.       {
  271.          while (RemoveAmigaGuideHostA(AmigaGuideHostHandle,NULL))
  272.             {
  273.                Delay(TICKS_PER_SECOND);
  274.             }
  275.       }
  276.    if (FileHandle)
  277.       {
  278.          DeleteFile(Filename);
  279.       }
  280.    if (ManDir) UnLock(ManDir);
  281.    if (MemoryPool) DeletePool(MemoryPool);
  282.    CloseLibrary(AmigaGuideBase);
  283.    CloseLibrary(UtilityBase);
  284.    CloseLibrary((struct Library *)IntuitionBase);
  285.    CloseLibrary((struct Library *)DOSBase);
  286.    MyExit(RC);
  287. }
  288.  
  289. /***********************************************/
  290.  
  291. static void InitThings(void)
  292.  
  293. {
  294.    struct Process *MyProcess;
  295.  
  296.    MyProcess=(struct Process *)FindTask(NULL);
  297.    if (MyProcess->pr_CLI)
  298.       {
  299.          WBStartupMessage=NULL;
  300.       }
  301.    else
  302.       {
  303.          do
  304.             {
  305.                WaitPort(&MyProcess->pr_MsgPort);
  306.             }
  307.          while (!(WBStartupMessage=(struct WBStartup *)GetMsg(&MyProcess->pr_MsgPort)));
  308.       }
  309.  
  310. #ifdef V39
  311.    if (!(DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",39)))
  312. #else
  313.    if (!(DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37)))
  314. #endif
  315.       {
  316.          MyExit(100);
  317.       }
  318.  
  319.    if (!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37)))
  320.       {
  321.          CloseLibrary((struct Library *)DOSBase);
  322.          MyExit(100);
  323.       }
  324.  
  325.    if (!(UtilityBase=OpenLibrary("utility.library",37)))
  326.       {
  327.          DisplayError("Unable to open utility.library V37");
  328.          CloseAll(RETURN_FAIL);
  329.       }
  330.  
  331.    if (!(AmigaGuideBase=OpenLibrary("amigaguide.library",34)))
  332.       {
  333.          DisplayError("Unable to open amigaguide.library V34");
  334.          CloseAll(RETURN_FAIL);
  335.       }
  336.  
  337.    if (!(MemoryPool=CreatePool(0,PUDDLESIZE,PUDDLESIZE)))
  338.       {
  339.          DisplayError("Unable to create memory pool");
  340.          CloseAll(RETURN_FAIL);
  341.       }
  342. }
  343.  
  344. /***********************************************/
  345.  
  346. static void AddDatabase(void)
  347.  
  348. {
  349.    #ifdef __GNUC__
  350.    static struct Hook AmigaGuideHook=
  351.       {
  352.          {NULL,NULL},
  353.          HookEntryA1,
  354.          AmigaGuideHostDispatcher,
  355.          NULL
  356.       };
  357.    #else
  358.    static struct Hook AmigaGuideHook=
  359.       {
  360.          {NULL,NULL},
  361.          AmigaGuideHostDispatcher,
  362.          NULL,
  363.          NULL
  364.       };
  365.    #endif
  366.  
  367.    char *t;
  368.  
  369.    Sprintf(DatabaseName,BASENAME ".%lx",FindTask(NULL));
  370.    Sprintf(Filename,"t:%s.guide",DatabaseName);
  371.  
  372.    if (!(FileHandle=Open(Filename,MODE_NEWFILE)))
  373.       {
  374.          DisplayDosError(Filename);
  375.          CloseAll(RETURN_ERROR);
  376.       }
  377.    t=DatabaseName;
  378.    if (VFPrintf(FileHandle,"@database %s.guide\n"
  379.                            "@node EnItSiRhC\n"
  380.                            "@endnode\n",&t)==-1)
  381.       {
  382.          DisplayDosError(Filename);
  383.          Close(FileHandle);
  384.          CloseAll(RETURN_ERROR);
  385.       }
  386.    Close(FileHandle);
  387.  
  388.    if (!(AmigaGuideHostHandle=AddAmigaGuideHostA(&AmigaGuideHook,DatabaseName,NULL)))
  389.       {
  390.          DisplayError("Unable to add dynamic amiga guide host");
  391.          CloseAll(RETURN_FAIL);
  392.       }
  393. }
  394.  
  395. /***********************************************/
  396.  
  397. static void OpenDatabase(void)
  398.  
  399. {
  400.    struct NewAmigaGuide NewAmigaGuide;
  401.  
  402.    NewAmigaGuide.nag_Lock=NULL;
  403.    NewAmigaGuide.nag_Name=Filename;
  404.    NewAmigaGuide.nag_Screen=NULL;
  405.    NewAmigaGuide.nag_PubScreen=NULL;
  406.    NewAmigaGuide.nag_HostPort=NULL;
  407.    NewAmigaGuide.nag_ClientPort=BASENAME;
  408.    NewAmigaGuide.nag_BaseName=BASENAME;
  409.    NewAmigaGuide.nag_Flags=HTF_NOACTIVATE;
  410.    NewAmigaGuide.nag_Context=NULL;
  411.    NewAmigaGuide.nag_Node=NULL;
  412.    NewAmigaGuide.nag_Line=0;
  413.    NewAmigaGuide.nag_Extens=NULL;
  414.    NewAmigaGuide.nag_Client=NULL;
  415.  
  416.    if (!(AmigaGuideHandle=OpenAmigaGuideA(&NewAmigaGuide,NULL)))
  417.       {
  418.          DisplayError("Unable to open amiga guide database");
  419.          CloseAll(RETURN_FAIL);
  420.       }
  421. }
  422.  
  423. /***********************************************/
  424.  
  425. #ifdef __GNUC__
  426. #define ICONBASE IconBase,
  427. #else
  428. #define ICONBASE
  429. #endif
  430.  
  431. static void GetParams(void)
  432.  
  433. {
  434.    if (WBStartupMessage)
  435.       {
  436.          struct Library *IconBase;
  437.  
  438.          if ((IconBase=OpenLibrary("icon.library",33)))
  439.             {
  440.                if (WBStartupMessage->sm_NumArgs)
  441.                   {
  442.                      BPTR OldCurrDir;
  443.                      struct DiskObject *DiskObject;
  444.                      OldCurrDir=CurrentDir(WBStartupMessage->sm_ArgList[0].wa_Lock);
  445.                      if ((DiskObject=GetDiskObject(ICONBASE WBStartupMessage->sm_ArgList[0].wa_Name)))
  446.                         {
  447.                            char *ManPath;
  448.                            if (!((ManPath=FindToolType(ICONBASE (UBYTE **)DiskObject->do_ToolTypes,"MANUALDIR")) ||
  449.                                  (ManPath=FindToolType(ICONBASE (UBYTE **)DiskObject->do_ToolTypes,"MANDIR")) ||
  450.                                  (ManPath=FindToolType(ICONBASE (UBYTE **)DiskObject->do_ToolTypes,"DIR"))))
  451.                               {
  452.                                  ManPath="man:";
  453.                               }
  454.                            if (!(ManDir=Lock(ManPath,SHARED_LOCK)))
  455.                               {
  456.                                  DisplayDosError(ManPath);
  457.                               }
  458.                            FreeDiskObject(ICONBASE DiskObject);
  459.                         }
  460.                      CurrentDir(OldCurrDir);
  461.                   }
  462.                CloseLibrary(IconBase);
  463.             }
  464.       }
  465.    else
  466.       {
  467.          struct
  468.             {
  469.                char *ManualDir;
  470.             } Arguments;
  471.  
  472.          struct RDArgs *RDArgs;
  473.  
  474.          Arguments.ManualDir="man:";
  475.          if (!(RDArgs=ReadArgs("MANUALDIR=MANDIR=DIR",(long *)&Arguments,NULL)))
  476.             {
  477.                PrintFault(IoErr(),NULL);
  478.                CloseAll(RETURN_FAIL);
  479.             }
  480.          if (!(ManDir=Lock(Arguments.ManualDir,SHARED_LOCK)))
  481.             {
  482.                DisplayDosError(Arguments.ManualDir);
  483.             }
  484.          FreeArgs(RDArgs);
  485.       }
  486.    if (!ManDir)
  487.       {
  488.          CloseAll(RETURN_FAIL);
  489.       }
  490. }
  491.  
  492. /***********************************************/
  493.  
  494. int ReadConfigFile(BPTR ConfigFile, struct ActionNode **ActionList)
  495.  
  496. {
  497.    BPTR OldInput;
  498.  
  499.    OldInput=SelectInput(ConfigFile);
  500.    while (TRUE)
  501.       {
  502.          struct
  503.             {
  504.                char *Pattern;
  505.                char *Action;
  506.             } CurrentLine;
  507.          struct RDArgs *LineArgs;
  508.  
  509.          while (TRUE)
  510.             {
  511.                int Character;
  512.  
  513.                Character=FGetC(ConfigFile);
  514.                if (Character!='\n' && Character!=' ' && Character!='\t')
  515.                   {
  516.                      if (Character==-1)
  517.                         {
  518.                            if (IoErr())
  519.                               {
  520.                                  return FALSE;
  521.                               }
  522.                            SelectInput(OldInput);
  523.                            return TRUE;
  524.                         }
  525.                      UnGetC(ConfigFile,Character);
  526.                      break;
  527.                   }
  528.             }
  529.          CurrentLine.Pattern=NULL;
  530.          CurrentLine.Action=NULL;
  531.          if (LineArgs=ReadArgs("P/A,A/A/F",(long *)&CurrentLine,NULL))
  532.             {
  533.                struct ActionNode *ActionNode;
  534.                int AllocSize, PatternSize;
  535.                PatternSize=2*strlen(CurrentLine.Pattern);
  536.                AllocSize=sizeof(struct ActionNode)+strlen(CurrentLine.Action)+PatternSize;
  537.                if ((ActionNode=Malloc(AllocSize)))
  538.                   {
  539.                      ActionNode->Pattern=Stpcpy(ActionNode->Action,CurrentLine.Action)+1;
  540.                      if (ParsePatternNoCase(CurrentLine.Pattern,ActionNode->Pattern,PatternSize)!=-1)
  541.                         {
  542.                            ActionNode->Next=*ActionList;
  543.                            *ActionList=ActionNode;
  544.                         }
  545.                      else
  546.                         {
  547.                            DisplayError("Error in pattern: %s",CurrentLine.Pattern);
  548.                            ActionNode=NULL;
  549.                         }
  550.                   }
  551.                FreeArgs(LineArgs);
  552.                if (!ActionNode)
  553.                   {
  554.                      return FALSE;
  555.                   }
  556.             }
  557.          else
  558.             {
  559.                return FALSE;
  560.             }
  561.       }
  562.    /* Not reached */
  563. }
  564.  
  565. /***********************************************/
  566.  
  567. static void ReadConfig(void)
  568.  
  569. {
  570.    static char *ConfigFile[]=
  571.       {
  572.          "PROGDIR:" CONFIGFILE,
  573.          "S:" CONFIGFILE,
  574.          "ENV:" CONFIGFILE
  575.       };
  576.  
  577.    int i;
  578.  
  579.    for (i=0; i<3; i++)
  580.       {
  581.          BPTR FileHandle;
  582.          if ((FileHandle=Open(ConfigFile[i],MODE_OLDFILE)))
  583.             {
  584.                int Result;
  585.  
  586.                Result=ReadConfigFile(FileHandle,&ActionList);
  587.                Close(FileHandle);
  588.                if (!Result)
  589.                   {
  590.                      DisplayDosError(ConfigFile[i]);
  591.                      CloseAll(RETURN_FAIL);
  592.                   }
  593.             }
  594.       }
  595. }
  596.  
  597. /***********************************************/
  598.  
  599. void Main(void);
  600.  
  601. void Main(void)
  602.  
  603. {
  604.    InitThings();
  605.    GetParams();
  606.    ReadConfig();
  607.    AddDatabase();
  608.    OpenDatabase();
  609.    CloseAll(RETURN_OK);
  610.    /* Not reached */
  611. }
  612.